﻿using System;
using System.Text;

namespace Kay.Communication.Framework
{
    /// <summary>
    /// 规定 Udp 数据包的头信息
    /// </summary>
    public class UdpDataPackageInfo
    {
        /// <summary>
        /// 标识
        /// <para>默认 32 个长度</para>
        /// </summary>
        public string Id { get; private set; }

        /// <summary>
        /// 总包个数
        /// <para>默认 10 个长度</para>
        /// </summary>
        public int Count { get; private set; }

        /// <summary>
        /// 当前包的索引（从 0 开始）
        /// <para>默认 10 个长度</para>
        /// </summary>
        public int Index { get; set; }

        /// <summary>
        /// 数据的实际长度
        /// </summary>
        public int Size { get; private set; }

        /// <summary>
        /// 发送机器网络终结点的字符串表示形式
        /// <para>默认 21 个长度</para>
        /// </summary>
        public string EndPointBySend { get; private set; }

        /// <summary>
        /// 接收机器网络终结点的字符串标识形式
        /// <para>默认 21 个长度</para>
        /// </summary>
        public string ToEndPointBySend { get; private set; }

        /// <summary>
        /// 消息使用的编码
        /// </summary>
        public Encoding Encoding { get; private set; }

        /// <summary>
        /// 发送机器网络终结点的字符串表示形式
        /// <para>默认 21 个长度</para>
        /// </summary>
        public string FromEndPointByReceive { get; private set; }

        /// <summary>
        /// 接收机器网络终结点的字符串标识形式
        /// <para>默认 21 个长度</para>
        /// </summary>
        public string EndPointByReceive { get; private set; }

        /// <summary>
        /// 包信息对应的数据
        /// </summary>
        public byte[] Bytes { get; private set; }

        /// <summary>
        /// 接收时间
        /// </summary>
        public DateTime ReceiveTime { get; private set; }

        /// <summary>
        /// 当前 DataPackage 长度的和
        /// </summary>
        public static int SumLength = 32 + 10 * 3 + 21 * 2;

        private UdpDataPackageInfo() { }

        /// <summary>
        /// 初始化一个新的数据包信息对象
        /// </summary>
        /// <param name="count">总包数</param>
        /// <param name="size">实际数据的大小</param>
        /// <param name="end">发送者网络终端文本表示形式</param>
        /// <param name="toEnd">接收者网络终端文本表示形式</param>
        /// <param name="encoding">消息使用的编码</param>
        /// <returns></returns>
        public static UdpDataPackageInfo GetNewDataPackageInfo(int count,int size,string end,string toEnd,Encoding encoding)
        {
            var package = new UdpDataPackageInfo
            {
                Id = Guid.NewGuid().ToString("N"),
                Count = count,
                Index = 0,
                Size = size,
                EndPointBySend = end,
                ToEndPointBySend = toEnd,
                Encoding = encoding
            };

            return package;
        }

        /// <summary>
        /// 初始化数据包并使用已有信息
        /// </summary>
        /// <param name="id">数据包标识</param>
        /// <param name="count">总包数</param>
        /// <param name="index">当前包索引</param>
        /// <param name="size">数据大小</param>
        /// <param name="end">发送者本地终结点</param>
        /// <param name="toEnd">接收者远程终结点</param>
        /// <param name="encoding">数据的编码格式</param>
        /// <param name="fromEnd">发送者远程终结点</param>
        /// <param name="currEnd">接收者本地终结点</param>
        /// <param name="bytes">数据</param>
        /// <returns></returns>
        public static UdpDataPackageInfo GetDataPackageInfo(string id, int count, int index, int size, string end, string toEnd, Encoding encoding, string fromEnd, string currEnd, byte[] bytes)
        {
            var package = new UdpDataPackageInfo
            {
                Id = id,
                Count = count,
                Index = index,
                Size = size,
                EndPointBySend = end,
                ToEndPointBySend = toEnd,
                Encoding = encoding,
                FromEndPointByReceive = fromEnd,
                EndPointByReceive = currEnd,
                Bytes = bytes,
                ReceiveTime = DateTime.Now
            };

            return package;
        }

        /// <summary>
        /// 获取当前包信息的字节表示形式
        /// </summary>
        /// <returns></returns>
        public byte[] GetBytes()
        {
            var sb = new StringBuilder();
            sb.Append(Id);
            sb.Append(Count.ToString().PadLeft(10, '0'));
            sb.Append(Index.ToString().PadLeft(10, '0'));
            sb.Append(Size.ToString().PadLeft(10, '0'));
            sb.Append(EndPointBySend.PadRight(21, char.MinValue));
            sb.Append(ToEndPointBySend.PadRight(21, char.MinValue));
            return Encoding.GetBytes(sb.ToString());
        }
    }
}